package cn.magicman.demo;

import java.util.LinkedList;
import java.util.Queue;

/**
 * 最简线程池（核心：任务队列+工作线程）
 * 功能：提交任务到队列，工作线程循环取任务执行（复用线程）
 */
public class RYOThreadPool {
    // 1. 任务队列（存储待执行的任务，用LinkedList简化）
    private final Queue<Runnable> taskQueue = new LinkedList<>();

    /**
     * 构造方法：初始化工作线程（固定数量）
     * @param threadCount 工作线程数量（比如2个）
     */
    public RYOThreadPool(int threadCount) {
        // 启动指定数量的工作线程
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                // 工作线程循环取任务（永远运行，直到程序结束）
                while (true) {
                    // 同步块：保证任务队列的线程安全（避免多线程同时操作队列）
                    synchronized (taskQueue) {
                        // 循环检查：如果队列空，等待（wait()会释放锁）
                        while (taskQueue.isEmpty()) {
                            try {
                                taskQueue.wait(); // 等待任务提交（被notify()唤醒）
                            } catch (InterruptedException e) {
                                return; // 中断则退出
                            }
                        }
                        // 取出队列头部的任务（FIFO：先进先出）
                        Runnable task = taskQueue.poll();
                        // 执行任务（捕获异常，避免工作线程崩溃）
                        try {
                            task.run();
                        } catch (Exception e) {
                            System.out.println("任务执行失败：" + e.getMessage());
                        }
                    }
                }
            }, "Worker-" + i).start(); // 启动工作线程
        }
    }

    /**
     * 提交任务到线程池
     * @param task 待执行的任务（非null）
     */
    public void submit(Runnable task) {
        synchronized (taskQueue) {
            taskQueue.offer(task); // 将任务加入队列尾部
            taskQueue.notify(); // 唤醒等待的工作线程（有新任务了）
        }
    }

    // ---------------------- 测试用例 ----------------------
    public static void main(String[] args) {
        // 1. 创建线程池：2个工作线程
        RYOThreadPool pool = new RYOThreadPool(2);

        // 2. 提交5个任务（模拟并发）
        for (int i = 0; i < 5; i++) {
            int taskId = i;
            pool.submit(() -> {
                System.out.println(Thread.currentThread().getName() + " 执行任务：" + taskId);
                try {
                    Thread.sleep(100); // 模拟任务耗时
                } catch (InterruptedException e) {
                    System.out.println("任务" + taskId + "被中断");
                }
            });
        }

        // 3. 主线程等待（避免程序提前结束）
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("所有任务执行完毕！");
    }
}